home *** CD-ROM | disk | FTP | other *** search
- /*
- File: FontHandler.c
-
- Contains: QuickDraw GX to PostScript conversion code.
-
- Version: Technology: Quickdraw GX 1.1.x
-
- Copyright: © 1991-1997 by Apple Computer, Inc., all rights reserved.
- */
-
- #include <GXExceptions.h>
- #include <String.h>
- #include <Resources.h>
- #include <MacMemory.h>
- #include <Collections.h>
- #include "IOUtilities.h"
- #include "GXToPSBuildConfig.h"
- #include "GXPrintingUniverse.h"
- #include "PSProcSetIDs.h"
- #include "FontDatabase.h"
- #include "FontHandler.h"
- #include "FontHandlerPrivate.h"
- #include "FontHandlerVariations.h"
-
- #ifdef resumeLabel
- #undef resumeLabel
- #endif
- #define resumeLabel(exception)
-
-
-
-
- /****************************************
-
- Function FHBuildPrinterFontList
-
- Function builds the printer font database from
- the document font database.
-
- hFHRec: Handle to a font handler record.
-
- *****************************************/
- OSErr FHBuildPrinterFontList(TFontHandlerHdl hFHRec);
- OSErr FHBuildPrinterFontList(TFontHandlerHdl hFHRec)
- {
- OSErr status;
- long nFonts; // Number of document fonts.
- long idx; // loop counter.
- long varCounter; // variation counter.
- gxFont theFont; // A particular document font.
- fhFont snapshotID; // snapshot id.
- TFontDbase docDbase; // the document font database.
- unsigned long *glyphBits; // glyph usage bits for a document font.
- TfdbInfoFlags fontFlags; // Font database flags for this font.
- long nGlyphs; // Number of glyphs in the font.
- long axisCount; // Number of variation axes supported by the font.
- long variationCount; // Number of variations used in this font.
- TFHStreamRequirements streamRequirements; // Streaming requirements for this font.
-
- docDbase = (*hFHRec)->docDbase;
-
- nrequire(status = FontDbaseCountFonts(docDbase, &nFonts), failed_FontCount);
- nrequire(status = FontDbaseLock(docDbase), failed_Lock);
-
- /*** For each document font, build the printer font items in the printer font database. **/
-
- for (idx = 1; idx <= nFonts; ++idx) {
-
- status = FontDbaseGetIndexedFont(docDbase, idx, &theFont);
- nrequire(status, failed_GetIndFont);
-
- status = FontDbaseGetFontInfo(docDbase, theFont, &nGlyphs, &axisCount, &variationCount, &fontFlags);
- nrequire(status, failed_info);
-
- status = FHGetStreamRequirements(theFont, (*hFHRec)->psDevice, (*hFHRec)->legalStreamTypes,
- (*hFHRec)->productDescription, &streamRequirements);
- nrequire(status, failed_testSnapshots);
-
- if (streamRequirements == fhNeedsSnapShots) {
-
- /** Make printer fonts for all of the variations **/
-
- for (varCounter = 1; varCounter <= variationCount; ++varCounter) {
-
- status = FontDbaseGetGlyphBits(docDbase, theFont, varCounter, &glyphBits, nil);
- nrequire(status, failed_bits);
-
- status = FHAddFontSnapShot(hFHRec, theFont, varCounter, &snapshotID);
- nrequire(status, failed_snapshot);
-
- status = FHAddPrinterFonts(hFHRec, snapshotID, glyphBits, nGlyphs, fontFlags);
- nrequire(status, failed_AddPrFont);
-
- }//end for
-
- } else {
-
- /*****
- Either the font doesn't need snapsonts or it can't be streamed,
- in any event, we only need one Snapshot for all variations (main bits)
- *****/
-
- status = FontDbaseGetGlyphBits(docDbase, theFont, eMainBits, &glyphBits, nil);
- nrequire(status, failed_bits);
-
- status = FHAddFontSnapShot(hFHRec, theFont, eMainBits, &snapshotID);
- nrequire(status, failed_snapshot);
-
- status = FHAddPrinterFonts(hFHRec, snapshotID, glyphBits, nGlyphs, fontFlags);
- nrequire(status, failed_AddPrFont);
-
- }//end if
-
- }//end for
-
- status = FontDbaseUnlock(docDbase);
- ncheck(status);
-
- failed_AddPrFont:
- failed_snapshot:
- failed_bits:
- failed_testSnapshots:
- failed_info:
- failed_GetIndFont:
- failed_Lock:
- failed_FontCount:
-
- return(status);
-
- }//FHBuildPrinterFontList
-
-
- //<FF>
- /****************************************
-
- Function: FHMakeProductDescripton
-
- Function combines the three components
- of the product description into the single
- C string necessary to pass in to the GXFlattenFont
- routine.
-
- productDescription: (returned) Pointer to description allocated here.
- version: Pascal string for version
- revision: Pascal string for revision
- product Pascal string for product-name.
-
- *****************************************/
- OSErr FHMakeProductDescription(unsigned char* *productDescription, unsigned char *version, unsigned char* revision, unsigned char* product);
- OSErr FHMakeProductDescription(unsigned char* *productDescription, unsigned char *version, unsigned char* revision, unsigned char* product)
- {
- OSErr status;
- unsigned char *p;
- short len;
- unsigned char wildcard[] = "\p*";
-
-
- if (!version)
- version = wildcard;
-
- if (!revision)
- revision = wildcard;
-
- if (!product)
- product = wildcard;
-
- /******
- Construct the combined product description string from the three components
- size: length of each plus spaces between plus nil at end
- ******/
- status = PrNewPtr((Ptr*)productDescription, version[0] + 1 + revision[0] + 1 + product[0] + 1);
- nrequire(status, failed_NewPtr);
-
- p = *productDescription;
- len = version[0];
- memcpy(p, &(version[1]), len); // copy the version string
- p[len] = ' '; // add a space;
- p += len + 1;
-
- len = revision[0];
- memcpy(p, &(revision[1]), len); // copy the revision string
- p[len] = ' '; // add a space;
- p += len + 1;
-
- len = product[0];
- memcpy(p, &(product[1]), len); // copy the revision string
- p[len] = 0x00; // add a null byte (pascal string)
-
- failed_NewPtr:
-
- return(status);
-
- }//FHMakeProductDescription
-
-
- //<FF>
- /****************************************
-
- Function: FontHandlerInit:
-
- Function initializes the font handler and returns a context.
-
- context: (returned) A font handler context.
- docFontDbase: A valid docuemnt font database.
- legalStreamTypes: legal font types for streaming.
- flags: Font Downloading flags.
- version: pascal string for PostScript version number.
- revision: pascal string for PostScript revision number.
- product: pascal string for PostScript product name.
-
- ****************************************/
- OSErr FontHandlerInit(TFontHandlerContext *context, CGXtoPostScriptDevice *psDevice, TFontDbase docFontDbase, scalerStreamTypeFlag legalStreamTypes, TFHDownloadFlags flags,
- unsigned char* version, unsigned char* revision, unsigned char* product)
- {
- OSErr status;
- TFontHandlerPtr pFHContext;
- Handle h;
- long i;
- unsigned char *productDescription;
-
- /** Allocate the context **/
-
- status = PrNewHandleClear((Handle*)context, sizeof(TFontHandlerRec));
- nrequire(status, failed_Alloc);
-
- /** Create the product descripton string **/
- status = FHMakeProductDescription(&productDescription, version, revision, product);
- nrequire(status, failed_product);
-
- /** Allocate the workspace handles **/
-
- for (i = 0; i < kMaxWrkSpaces; ++i) {
-
- nrequire(status = PrNewHandle(&h, 0), failed_WorkSpace); // Allocate workspace handle.
- pFHContext = *((TFontHandlerHdl)*context);
- pFHContext->workHandle[i] = h;
- pFHContext->workSize[i] = 0;
-
- #if DEBUGLEVEL > 0
- pFHContext->workHandleInUse[i] = false;
- #endif
-
- }//end for
-
- HLock((Handle) *context ); pFHContext = *((TFontHandlerHdl)*context);
-
- pFHContext->psDevice = psDevice;
- pFHContext->legalStreamTypes = legalStreamTypes;
- pFHContext->asciiDownload = (flags & fhDownloadAscii) ? true : false;
- pFHContext->useTypeZeroFonts = (flags & fhUseTypeZeroFonts) ? true : false;
- pFHContext->productDescription = (char*)productDescription;
- pFHContext->nextOffset = 0;
- pFHContext->docDbase = docFontDbase;
- pFHContext->numPrFonts = 0;
- pFHContext->saveLevel = 0;
- pFHContext->nextSnapShot = 1; // start snapshot id's at one. zero means not found.
- pFHContext->printerVM = 100000; // Just an initial value in case client doesn't set it.
- pFHContext->vmAvailable = pFHContext->printerVM;
-
- pFHContext->documentStreamTypes = 0;
-
- status = FHCanPrinterHandleAllFonts(product, &(pFHContext->printerCanDoAllFonts) );
- nrequire(status, failed_printerCan);
-
- pFHContext = *((TFontHandlerHdl)*context);
- nrequire(status = RDInit(psDevice, &(pFHContext->rdMap)), failed_RD);
-
- /** Allocate the collections **/
-
- require_action(pFHContext->printerFontsOffsets = NewCollection(), failed_Collection, status = MemError(););
- require_action(pFHContext->snapShots = NewCollection(), failed_Collection1, status = MemError(););
-
- HUnlock((Handle) *context );
-
- /**********************
- Now build the printer font database entries
- based on the document font database.
- ***********************/
-
- status = FHBuildPrinterFontList((TFontHandlerHdl)*context);
- nrequire(status, failed_PrinterFonts);
-
- /********
- Since building the printer font list did memory size querries for all downloaded fonts
- and the the queries accumulate the returned stream types from the query,
- the documentStreamTypes field in our context contains all font types necessary for
- the document based on the document font database. If the document did not require
- true-type streaming (using patch) then disable the bit in the legal stream types field
- that we use for streaming.
- *********/
-
- pFHContext = *((TFontHandlerHdl)*context); // in case it moved.
-
- if ( !(pFHContext->documentStreamTypes & truetypeStreamType) ) {
-
- pFHContext->legalStreamTypes &= ~truetypeStreamType;
-
- #if DEBUGLEVEL >= DEBUGFEEDBACK
- dprintf(trace, "Document did not need TT scaler, disabling trueTypeStreamType");
- #endif
-
- }//end if
-
-
- failed_PrinterFonts:
-
- pFHContext = *((TFontHandlerHdl)*context);
-
- if (status != noErr)
- DisposeCollection(pFHContext->printerFontsOffsets);
-
- failed_Collection1:
- failed_Collection:
-
- if (status != noErr) {
- OSErr saveStatus;
-
- pFHContext = *((TFontHandlerHdl)*context);
- saveStatus = RDShutdown(pFHContext->rdMap);
- ncheck(saveStatus);
-
- }//end if
-
- failed_RD:
-
- failed_printerCan:
-
- failed_WorkSpace:
- /** If we failed after any workspaces were allocated, dispose of any that were allocated **/
-
- if (status != noErr) {
-
- for (i = 0; i < kMaxWrkSpaces; ++i) {
-
- pFHContext = *((TFontHandlerHdl)*context);
- h = pFHContext->workHandle[i];
- if (h != nil)
- DisposeHandle(h);
-
- }//end for
-
- /* Dispose of the pointer allocated for the product description */
- DisposePtr((Ptr)productDescription);
-
- }//end if
-
-
- failed_product:
- if (status != noErr)
- DisposeHandle((Handle)*context);
-
- failed_Alloc:
-
- ncheck(status);
-
- if (status != noErr) // make sure we return nil if an error happened.
- *context = nil;
-
- return(status);
-
- }//FontHandlerInit
-
-
- //<FF>
- /**********************************************
-
- Function: FontHandlerShutdown
-
- Function disposes of a font handler context.
-
- context: Font handler context to dispose of
-
- ***********************************************/
- OSErr FontHandlerShutdown(TFontHandlerContext context)
- {
- OSErr status, saveStatus;
- register TFontHandlerPtr pFHContext;
- long i;
- Handle h;
- long offset;
- TPrinterFontRec *printerFont;
-
- HLock((Handle)context);
- pFHContext = *(TFontHandlerHdl)(context);
-
-
- /* Dispose of any allocations haning off printer fonts */
-
- saveStatus = noErr; /* in case #items == 0 and loop won't execute */
-
- for (i = 1; i <= CountCollectionItems(pFHContext->printerFontsOffsets); ++i) {
-
- saveStatus = GetIndexedCollectionItem(pFHContext->printerFontsOffsets, i, nil, &offset);
- nrequire(saveStatus, failed_GetItem);
-
- printerFont = (TPrinterFontRec*)(pFHContext->printerFonts + offset);
-
- h = printerFont->glyphToCharCodeMap;
-
- if (h != nil)
- DisposeHandle(printerFont->glyphToCharCodeMap);
-
- }//end for
-
- failed_GetItem:
- /* Dispose of the collections */
-
- DisposeCollection(pFHContext->printerFontsOffsets);
- DisposeCollection(pFHContext->snapShots);
-
- /* Dispose of the workspace handles */
-
- for (i = 0; i < kMaxWrkSpaces; ++i) {
-
- h = pFHContext->workHandle[i];
- if (h != nil)
- DisposeHandle(h);
-
- }//end for
-
- /* Dispose of the product description string */
-
- DisposePtr(pFHContext->productDescription);
-
- /* dispose of the RDMap */
-
- status = RDShutdown(pFHContext->rdMap);
- ncheck(status);
-
- /* Dispose of our context */
-
- DisposeHandle((Handle)context);
-
- if (saveStatus != noErr)
- status = saveStatus;
-
- return(status);
-
- }//FontHandlerShutdown
-
-
-
-
- /************************************
-
- Function: FontHandlerLockContext
-
- Routine to lock font handler data in memory.
-
- *************************************/
- OSErr FontHandlerLockContext(TFontHandlerContext context)
- {
- HLock((Handle)context);
- return(MemError());
-
- }//FontHandlerLockContext
-
-
-
-
- /************************************
-
- Function: FontHandlerUnlockContext
-
- Routine to unlock font handler data in memory.
-
- *************************************/
- OSErr FontHandlerUnlockContext(TFontHandlerContext context)
- {
- HUnlock((Handle)context);
- return(MemError());
-
- }//FontHandlerUnlockContext
-
-
- #if USECONTROLRESOURCES
- /**********************************************
- Routine FontHandlerGetProcSetList
- Returns the range of id's and type of the resources for the
- PostScript Procedure set, based upon the parameters specified at init time.
-
- context: A valid imaging engine context.
- needsHex: Boolean indicating whether printer requires hex rather than binary.
-
- ************************************************/
- OSErr FontHandlerGetProcSetList(TFontHandlerContext context, gxProcSetListPtr procSetList, Boolean needsHex)
- {
- TFontHandlerPtr pFHRec = *(TFontHandlerHdl)context;
- Boolean needsScaler = false;
-
- if ( pFHRec->legalStreamTypes & truetypeStreamType)
- needsScaler = true;
-
- procSetList->controlType = kControlResType;
- procSetList->dataType = kBinaryResType;
-
- if (!needsScaler)
- procSetList->controlid = kFHControlResID;
- else
- if (needsHex)
- procSetList->controlid = kFHControlResID + 1;
- else
- procSetList->controlid = kFHControlResID + 2;
-
- return(noErr);
- }//FontHandlerGetProcSetList
-
- #else
-
- /***
- This function directly downloads the font handler proceset.
- Note: In the library version we do not deal with the TrueType scaler.
- Note, this version does not need a font handler context, just a device.
- ****/
- OSErr FontHandlerDownloadProcSetList(CGXtoPostScriptDevice *theDevice)
- {
- OSErr status = noErr;
- Handle hProc;
-
- status = FetchResource('wstr', kFHProcCopyRightNoticeID, &hProc);
- nrequire(status, failed_fetchResource);
- HLock(hProc);
- short size = *(short*)(*hProc);
- char* data = (*hProc) + sizeof(short); // skip past size word in wstr resource.
- status = theDevice->BufferData(data, size, gxNoBufferOptions);
- ReleaseResource(hProc);
-
- if (status == noErr) {
- status = FetchResource('wstr', kFHStartProcId, &hProc);
- nrequire(status, failed_fetchResource1);
- HLock(hProc);
- size = *(short*)(*hProc);
- data = (*hProc) + sizeof(short); // skip past size word in wstr resource.
- status = theDevice->BufferData(data, size, gxNoBufferOptions);
- ReleaseResource(hProc);
- }//end if
-
- if (status == noErr) {
- status = FetchResource('wstr', kFHStartProcId + 1, &hProc);
- nrequire(status, failed_fetchResource2);
- HLock(hProc);
- size = *(short*)(*hProc);
- data = (*hProc) + sizeof(short); // skip past size word in wstr resource.
- status = theDevice->BufferData(data, size, gxNoBufferOptions);
- ReleaseResource(hProc);
- }//end if
-
- failed_fetchResource2:
- failed_fetchResource1:
- failed_fetchResource:
- return(status);
-
- }//FontHandlerDownloadProcSetList
-
- #endif
-
- /*************************************************
-
- Routine: FontHandlerSetFontVM
-
- Routine called by client to let font handler know
- how much VM is available for fonts.
-
- **************************************************/
- OSErr FontHandlerSetFontVM(TFontHandlerContext context, long fontVM)
- {
- TFontHandlerPtr pFHRec = *(TFontHandlerHdl)context;
-
- #if DEBUGLEVEL >= DEBUGFEEDBACK
- dprintf(trace, "Font VM passed in: %d", fontVM);
- #endif
-
- pFHRec->printerVM = fontVM;
- pFHRec->vmAvailable = fontVM;
-
- return(noErr);
-
- }//FontHandlerSetFontVM
-
-